﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ElectronicDiary.Models;
using ElectronicDiary.Models.Admin;
using ElectronicDiary.ViewModels.Admin;
using System.Web.Security;
using System.Web.Routing;

namespace ElectronicDiary.Controllers
{    
    [Authorize(Roles = "Admin")]
    public class AdminController : Controller
    {
        //
        // GET: /Admin/
        //private electronicDiaryEntities db = new electronicDiaryEntities();

        public ActionResult Panel()
        {
            return View();
        }

        [ChildActionOnly]
        public ActionResult Menu()
        {
            return PartialView();
        }

        public ActionResult ParentsView()
        {
            using (var context = new electronicDiaryEntities())
            {
                Parent[] parents = context.parent.Select(
                    n => new Parent
                    {
                        ID = n.UserId,
                        FName = n.firstName,
                        LName = n.lastName,
                        Active = n.Active
                    }).ToArray();

                return View(parents);
            }
        }

        public ActionResult ParentAdd()
        {
            return View();
        }

        [HttpPost]
        public ActionResult ParentAdd(ParentEditAddModel model)
        {
            if (ModelState.IsValid)
            {
                MembershipCreateStatus createStatus;
                Membership.CreateUser(model.Login, model.Password, model.Mail, null, null, true, null, out createStatus);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    Guid role;
                    int id;
                    using (var context = new electronicDiaryEntities())
                    {
                        id = context.parent.Max(n=>n.idParent) + 1;
                        model.UserId = context.aspnet_Users.SingleOrDefault(n=>n.LoweredUserName == model.Login.ToLower()).UserId;
                        role = context.aspnet_Roles.SingleOrDefault(n=>n.LoweredRoleName == "parent").RoleId;
                        parent p = parent.Createparent(id, model.FName, model.LName, model.City, model.ZipCode, model.StreetName, model.Number, model.UserId, true);
                        Roles.AddUserToRole(model.Login.ToLower(), "parent");
                        
                        if (model.ContactNumber != null)
                        {
                            p.contatnumber = model.ContactNumber;
                        }
                        context.parent.AddObject(p);
                        context.SaveChanges();
                    }
                    return RedirectToAction("ParentsView", "Admin");
                }
                else
                {
                    ModelState.AddModelError("", ErrorCodeToString(createStatus));
                }
            }

            return View(model);
        }

        public ActionResult ParentEdit(Guid id)
        {
            using (var context = new electronicDiaryEntities())
            {
                ParentEditAddModel parent = context.parent.Select(
                        n => new ParentEditAddModel
                        {
                            Login = n.aspnet_Membership.aspnet_Users.LoweredUserName,
                            Mail = n.aspnet_Membership.Email,
                            FName = n.firstName,
                            LName = n.lastName,
                            City = n.city,
                            ContactNumber = n.contatnumber,
                            Number = n.number,
                            StreetName = n.streetName,
                            UserId = n.UserId,
                            ZipCode = n.zipCode,
                            Active = n.Active,
                            Password = n.aspnet_Membership.Password
                        }
                    ).Where(n => n.UserId == id).First();

                return View(parent);
            }
        }

        [HttpPost]
        public ActionResult ParentEdit(ParentEditAddModel p)
        {
            using (var context = new electronicDiaryEntities())
            {
                parent user = context.parent.SingleOrDefault(n => n.UserId == p.UserId);
                user.aspnet_Membership.aspnet_Users.UserName = p.Login;
                user.aspnet_Membership.aspnet_Users.LoweredUserName = p.Login.ToLower();
                user.aspnet_Membership.Email = p.Mail;
                user.aspnet_Membership.LoweredEmail = p.Mail.ToLower();
                user.city = p.City;
                user.contatnumber = p.ContactNumber;
                user.firstName = p.FName;
                user.lastName = p.LName;
                user.number = p.Number; ;
                user.streetName = p.StreetName;
                user.zipCode = p.ZipCode;
                user.Active = p.Active;

                context.ApplyCurrentValues<parent>("parent", user);
                context.SaveChanges();
            }

            return RedirectToAction("ParentsView");
        }

        public ActionResult SubjectsView()
        {
            using (var context = new electronicDiaryEntities())
            {
                Subject[] subjects = context.subject
                    .Select(n => new Subject
                    {
                        ID = n.idSubject,
                        Name = n.name
                    }).ToArray();


                return View(subjects);
            }
        }

        [HttpPost]
        public ActionResult SubjectAdd(SubjectEditAddModel sub)
        {
            if (ModelState.IsValid)
            {
                using (var context = new electronicDiaryEntities())
                {
                    context.subject.AddObject(subject.Createsubject(1, sub.Name));
                    context.SaveChanges();
                }
                return RedirectToAction("SubjectsView", "Admin");
            }
            return View(sub);
        }

        public ActionResult SubjectAdd()
        {
            return View();
        }

        public ActionResult SubjectEdit(int id)
        {
            using (var context = new electronicDiaryEntities())
            {
                SubjectEditAddModel sub = context.subject
                    .Where(n => n.idSubject == id)
                    .Select(n => new SubjectEditAddModel
                    {
                        ID = id,
                        Name = n.name
                    }).First();

                return View(sub);
            }
        }

        [HttpPost]
        public ActionResult SubjectEdit(SubjectEditAddModel sub)
        {
            if (ModelState.IsValid)
            {
                using (var context = new electronicDiaryEntities())
                {
                    subject subject = context.subject.SingleOrDefault(n => n.idSubject == sub.ID);
                    subject.name = sub.Name;

                    context.ApplyCurrentValues<subject>("subject", subject);
                    context.SaveChanges();
                }

                return RedirectToAction("SubjectsView", "Admin");
            }

            return View(sub);
        }

        public ActionResult StudentsView()
        {
            using (var context = new electronicDiaryEntities())
            {
                Student[] s = context.student
                    .Select(n => new Student
                    {
                        ID = n.idStudent,
                        FName = n.firstName,
                        LName = n.lastName,
                        ClassName = n.@class.Name,
                        Active = n.Active
                    }).ToArray();
                return View(s);
            }
        }

        public ActionResult StudentAdd()
        {
            return View(new StudentEditAddModel());
        }

        [HttpPost]
        public ActionResult StudentAdd(StudentEditAddModel st)
        {
            if (ModelState.IsValid)
            {
                using (var context = new electronicDiaryEntities())
                {
                    student student = student.Createstudent(1, st.FName, st.LName, st.BirthDate, st.IDClass, st.IDParent, st.City, st.ZipCode, st.StreetName, st.Number, true);
                    context.student.AddObject(student);
                    context.SaveChanges();
                }
                return RedirectToAction("StudentsView", "Admin");
            }
            return View(st);
        }

        public ActionResult StudentEdit(int id)
        {
            using (var context = new electronicDiaryEntities())
            {
                StudentEditAddModel seam = context.student
                    .Where(n => n.idStudent == id)
                    .Select(n => new StudentEditAddModel
                    {
                        Active = n.Active,
                        BirthDate = n.dtBirthDate,
                        City = n.city,
                        FName = n.firstName,
                        ID = id,
                        IDClass = n.idClass,
                        IDParent = n.idParent,
                        LName = n.lastName,
                        Number = n.number,
                        StreetName = n.streetName,
                        ZipCode = n.zipCode
                    }).First();

                return View(seam);
            }
        }

        [HttpPost]
        public ActionResult StudentEdit(StudentEditAddModel st)
        {
            if (ModelState.IsValid)
            {
                using (var context = new electronicDiaryEntities())
                {
                    student s = context.student.SingleOrDefault(n => n.idStudent == st.ID);
                    s.Active = st.Active;
                    s.city = st.City;
                    s.dtBirthDate = st.BirthDate;
                    s.firstName = st.FName;
                    s.idClass = st.IDClass;
                    s.idParent = st.IDParent;
                    s.lastName = st.LName;
                    s.number = st.Number;
                    s.streetName = st.StreetName;
                    s.zipCode = st.ZipCode;

                    context.ApplyCurrentValues<student>("student", s);
                    context.SaveChanges();
                }
                return RedirectToAction("StudentsView", "Admin");
            }
            return View(st);
        }

        public ActionResult StudentsClassesView()
        {
            using (var context = new electronicDiaryEntities())
            {
                StudentsClass[] sc = context.@class
                    .Select(n => new StudentsClass
                    {
                        ID = n.idClass,
                        Teacher = n.teacher.firstName + " " + n.teacher.lastName,
                        Name = n.Name,
                        Profile = n.Profile,
                        startDate = n.dtStartDate,
                        endDate = n.dtEndDate
                    }).ToArray();
                return View(sc);
            }
        }

        public ActionResult StudentsClassAdd()
        {
            return View(new StudentsClassEditAddModel());
        }        

        [HttpPost]
        public ActionResult StudentsClassAdd(StudentsClassEditAddModel sc )
        {
            if (ModelState.IsValid)
            {
                using (var context = new electronicDiaryEntities())
                {
                    @class cs = @class.Createclass(1, sc.IDTeacher, sc.StartDate, sc.Name);
                    cs.Profile = sc.Profile;
                    cs.dtEndDate = sc.EndDate;
                    context.@class.AddObject(cs);
                    context.SaveChanges();
                }
                return RedirectToAction("StudentsClassesView", "Admin");
            }

            return View(sc);
        }

        public ActionResult StudentsClassEdit(int id)
        {
            using (var context = new electronicDiaryEntities())
            {
                StudentsClassEditAddModel sc = context.@class
                    .Where(n => n.idClass == id)
                    .Select(n => new StudentsClassEditAddModel
                    {
                        ID = n.idClass,
                        IDTeacher = n.idTeacher,
                        EndDate = n.dtEndDate,
                        Name = n.Name,
                        Profile = n.Profile,
                        StartDate = n.dtStartDate
                    }).First();

                return View(sc);
            }
        }

        [HttpPost]
        public ActionResult StudentsClassEdit(StudentsClassEditAddModel sc)
        {
            if (ModelState.IsValid)
            {
                using (var context = new electronicDiaryEntities())
                {
                    @class c = context.@class.SingleOrDefault(n => n.idClass == sc.ID);
                    c.dtEndDate = sc.EndDate;
                    c.dtStartDate = sc.StartDate;
                    c.idTeacher = sc.IDTeacher;
                    c.Name = sc.Name;
                    c.Profile = sc.Profile;

                    context.ApplyCurrentValues<@class>("class", c);
                    context.SaveChanges();
                }
                return RedirectToAction("StudentsClassesView");
            }

            return View(sc);
        }

        public ActionResult TeachersView()
        {
            using (var context = new electronicDiaryEntities())
            {
                Teacher[] teachers = context.teacher
                    .Select(n => new Teacher
                    {
                        ID = n.UserId,
                        FName = n.firstName,
                        LName = n.lastName,
                        contactNumber = n.contactNumber,
                        Active = n.Active
                    }).ToArray();
                return View(teachers);
            }
        }

        public ActionResult TeacherAdd()
        {
            return View();
        }

        [HttpPost]
        public ActionResult TeacherAdd(TeacherEditAddModel model)
        {
            if (ModelState.IsValid)
            {
                MembershipCreateStatus createStatus;
                Membership.CreateUser(model.Login, model.Password, model.Mail, null, null, true, null, out createStatus);

                if (createStatus == MembershipCreateStatus.Success)
                {
                    Guid role;
                    int id;
                    using (var context = new electronicDiaryEntities())
                    {
                        id = context.parent.Max(n => n.idParent) + 1;
                        model.UserId = context.aspnet_Users.SingleOrDefault(n => n.LoweredUserName == model.Login.ToLower()).UserId;
                        role = context.aspnet_Roles.SingleOrDefault(n => n.LoweredRoleName == "parent").RoleId;
                        teacher t = teacher.Createteacher(id, model.FName, model.LName, model.UserId, true);
                        Roles.AddUserToRole(model.Login.ToLower(), "teacher");

                        if (model.ContactNumber != null)
                        {
                            t.contactNumber = model.ContactNumber;
                        }
                        context.teacher.AddObject(t);
                        context.SaveChanges();
                    }
                    return RedirectToAction("TeachersView", "Admin");
                }
                else
                {
                    ModelState.AddModelError("", ErrorCodeToString(createStatus));
                }
            }

            return View(model);
        }

        public ActionResult TeacherEdit(Guid id)
        {
            using (var context = new electronicDiaryEntities())
            {
                TeacherEditAddModel teacher = context.teacher.Select(
                        n => new TeacherEditAddModel
                        {
                            Login = n.aspnet_Membership.aspnet_Users.LoweredUserName,
                            Mail = n.aspnet_Membership.Email,
                            FName = n.firstName,
                            LName = n.lastName,                            
                            ContactNumber = n.contactNumber,
                            UserId = n.UserId,
                            Active = n.Active
                        }
                    ).Where(n => n.UserId == id).First();
                return View(teacher);
            }
        }

        [HttpPost]
        public ActionResult TeacherEdit(TeacherEditAddModel p)
        {
            using (var context = new electronicDiaryEntities())
            {
                teacher user = context.teacher.SingleOrDefault(n => n.UserId == p.UserId);
                user.aspnet_Membership.aspnet_Users.UserName = p.Login;
                user.aspnet_Membership.aspnet_Users.LoweredUserName = p.Login.ToLower();
                user.aspnet_Membership.Email = p.Mail;
                user.aspnet_Membership.LoweredEmail = p.Mail.ToLower();
                user.contactNumber = p.ContactNumber;
                user.firstName = p.FName;
                user.lastName = p.LName;
                user.Active = p.Active;

                context.ApplyCurrentValues<teacher>("teacher", user);
                context.SaveChanges();
            }

            return RedirectToAction("TeachersView");
        }

        public ActionResult UserDelete(Guid id, string role)
        {
            string user;
            using (var context = new electronicDiaryEntities())
            {
                user = context.aspnet_Users.SingleOrDefault(n => n.UserId == id).UserName;

                Membership.DeleteUser(user);

                DeleteModel del = new DeleteModel();

                if (role == "teacher")
                {
                    teacher t = context.teacher.SingleOrDefault(n => n.UserId == id);
                    t.Active = false;
                    context.ApplyCurrentValues<teacher>("teacher", t);
                    context.SaveChanges();

                    del.Role = "Nauczyciela";
                    del.Site = "~/Admin/TeachersView";
                }
                else if (role == "parent")
                {
                    parent p = context.parent.SingleOrDefault(n => n.UserId == id);
                    p.Active = false;
                    context.ApplyCurrentValues<parent>("parent", p);
                    context.SaveChanges();

                    del.Role = "Rodzica";
                    del.Site = "~/Admin/ParentsView";
                }
                return View(del);
            }
        }

        #region Status Codes
        private static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // See http://go.microsoft.com/fwlink/?LinkID=177550 for
            // a full list of status codes.
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "User name already exists. Please enter a different user name.";

                case MembershipCreateStatus.DuplicateEmail:
                    return "A user name for that e-mail address already exists. Please enter a different e-mail address.";

                case MembershipCreateStatus.InvalidPassword:
                    return "The password provided is invalid. Please enter a valid password value.";

                case MembershipCreateStatus.InvalidEmail:
                    return "The e-mail address provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidAnswer:
                    return "The password retrieval answer provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidQuestion:
                    return "The password retrieval question provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.InvalidUserName:
                    return "The user name provided is invalid. Please check the value and try again.";

                case MembershipCreateStatus.ProviderError:
                    return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                case MembershipCreateStatus.UserRejected:
                    return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";

                default:
                    return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
            }
        }
        #endregion
    }
}
